package com.caregiver.watch.business.data.enums;

import com.caregiver.watch.business.care.model.vo.SportDataDetailVo;
import com.caregiver.watch.business.care.model.vo.SportDataDetailVo.SportDataDetail;
import com.caregiver.watch.business.data.model.po.SportData;
import com.caregiver.watch.common.utils.time.DateUtils;
import lombok.Getter;
import org.apache.commons.collections4.CollectionUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.caregiver.watch.common.constant.NumberConstants.ONE;
import static com.caregiver.watch.common.constant.NumberConstants.ZERO;

/**
 * @Description: 运动类型枚举
 * @Author 疆戟
 * @Date 2025/9/27 10:49
 * @Version 1.0
 */
@Getter
public enum SportTypeEnum {

    /**
     * 游泳
     * 登山
     * 跑步
     * 骑行
     * 步行
     * 篮球
     * 瑜伽
     */
    SWIMMING( "游泳", 0x83, 0xB4) {

        @Override
        public SportDataDetail buildSportDataDetail(List<SportData> data) {
            if (CollectionUtils.isEmpty(data)) {
                return null;
            }
            SportData firstSportData = data.get(ZERO);
            SportData lastSportData = data.get(data.size() - ONE);
            SportDataDetail detail = new SportDataDetail();
            detail.setSportType(this);
            detail.setDuration(calculateDuration(firstSportData.getDataTime(), lastSportData.getDataTime()));
            return detail;
        }
    },
    WALKING("步行", 0x01) {

        @Override
        public SportDataDetail buildSportDataDetail(List<SportData> data) {
            if (CollectionUtils.isEmpty(data)) {
                return null;
            }
            SportDataDetail detail = new SportDataDetail();
            detail.setSportType(this);
            detail.setDistance(calculateDistance(data));
            return detail;
        }
    },
    CLIMBING("登山", 0x05) {

        @Override
        public SportDataDetail buildSportDataDetail(List<SportData> data) {
            if (CollectionUtils.isEmpty(data)) {
                return null;
            }
            SportDataDetail detail = new SportDataDetail();
            detail.setSportType(this);
            detail.setDistance(calculateDistance(data));
            return detail;
        }
    },
    RUNNING( "跑步", 0x07) {

        @Override
        public SportDataDetail buildSportDataDetail(List<SportData> data) {
            if (CollectionUtils.isEmpty(data)) {
                return null;
            }
            SportDataDetail detail = new SportDataDetail();
            detail.setSportType(this);
            detail.setDistance(calculateDistance(data));
            return detail;
        }
    },
    RIDING( "骑行", 0x88, 0x9C) {

        @Override
        public SportDataDetail buildSportDataDetail(List<SportData> data) {
            if (CollectionUtils.isEmpty(data)) {
                return null;
            }
            SportDataDetail detail = new SportDataDetail();
            detail.setSportType(this);
            detail.setDistance(calculateDistance(data));
            return detail;
        }
    },
    // 球类运动
    BASKETBALL("篮球", 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x91, 0x92,0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xEE) {

        @Override
        public SportDataDetail buildSportDataDetail(List<SportData> data) {
            if (CollectionUtils.isEmpty(data)) {
                return null;
            }
            SportData firstSportData = data.get(ZERO);
            SportData lastSportData = data.get(data.size() - ONE);
            SportTypeEnum sportType = SportTypeEnum.parse(firstSportData.getSportType());
            SportDataDetail detail = new SportDataDetail();
            detail.setSportType(sportType);
            detail.setDuration(calculateDuration(firstSportData.getDataTime(), lastSportData.getDataTime()));
            return detail;
        }
    },
    OTHER("其他") {

        @Override
        public SportDataDetail buildSportDataDetail(List<SportData> data) {
            if (CollectionUtils.isEmpty(data)) {
                return null;
            }
            SportData firstSportData = data.get(ZERO);
            SportData lastSportData = data.get(data.size() - ONE);
            SportTypeEnum sportType = SportTypeEnum.parse(firstSportData.getSportType());
            SportDataDetail detail = new SportDataDetail();
            detail.setSportType(sportType);
            detail.setDuration(calculateDuration(firstSportData.getDataTime(), lastSportData.getDataTime()));
            return detail;
        }
    };

    private final Set<Integer> codes;
    private final String name;

    SportTypeEnum(String name, Integer... codes) {
        this.codes = Stream.of(codes).collect(Collectors.toSet());
        this.name = name;
    }


    public static SportTypeEnum parse(Integer code) {
        for (SportTypeEnum value : values()) {
            if (value.codes.contains(code)) {
                return value;
            }
        }
        return OTHER;
    }

    /**
     * 统计时长
     * @param startTime
     * @param endTime
     * @return
     */
    protected Integer calculateDuration(LocalDateTime startTime, LocalDateTime endTime) {
        return DateUtils.getTimeBetween(startTime, endTime, TimeUnit.MINUTES);
    }

    /**
     * 统计距离
     * @param data
     * @return
     */
    protected BigDecimal calculateDistance(List<SportData> data) {
        if (CollectionUtils.isEmpty(data)) {
            return  BigDecimal.ZERO;
        }
        // 距离之和
        return data.stream()
                .map(sportData -> sportData.getDistance())
                .filter(distance -> distance != null)
                .collect(Collectors.reducing(BigDecimal.ZERO, BigDecimal::add));
    }


    public abstract SportDataDetail buildSportDataDetail(List<SportData> data);


}
